<!DOCTYPE html>
<html>
	<head>
		<meta charset=utf-8>
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<title>透明版3d机房</title>
		<style>
			body { margin: 0; border: 0; padding: 0; width: 100%; height: 100%; overflow: hidden;}
			canvas { width: 100%; height: 100%; }
          /* #container { width: 100%; height: 100%; display: inline-block; float: left;} */
			#info {
				position: absolute;
				padding: 10px;
				background: rgba(255, 255, 255, 0.6);
				line-height: 1;
				border-radius: 5px;	
				width: 100px;
				top: 50%;
				left: 50%;
				display: none;
			}
		</style>
	</head>
	<body>
      <div id="container"></div>
      <div id="info"></div>
      
      
      <script src="js/three.min.js"></script>
      <script src="js/Detector.js"></script>
      <script src="js/Stats.js"></script>
      <script src="js/OrbitControls.js"></script>
      //<script src="js/KeyboardState.js"></script>
      <script src="js/Projector.js"></script>
      
		<script>
          var container = document.getElementById("container");
          var scene, camera, renderer, controls, stats;
          var clock = new THREE.Clock();
          
          var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight; 

          var targetList = [];
          var projector, mouse = { x: 0, y: 0 };
          
          // loginfo
          var info = document.getElementById("info");
          
          function loginfo(log, event) {
            //info.innerHTML += log;
            //info.innerHTML += "<br />";
			// 获取鼠标移入的对象的信息
			info.innerHTML = log;
			// 通过event获取鼠标位置，然后重新给Info定义位置
			// 调用修改div的函数
			console.log(event);
			renderDiv(event);
          }
		  
		  
          
          // 定义机柜、服务器数据
          var model = [
            {
              cabinet: 
              {
                'uuid': '1',
                'id': 1, 
                'name':'1号机柜', 
                'size': {w: 30, h: 70, d: 30}, 
                'position': {x: -10, y: 0, z: 50},
                'servers': [
                  {'uuid': '11', 'id':11, 'name':'1号服务器', 'ip':'', 'apps': ''},
                  {'uuid': '12', 'id':12, 'name':'2号服务器', 'ip':'', 'apps': ''},
                  {'uuid': '13', 'id':13, 'name':'3号服务器', 'ip':'', 'apps': ''},
                  {'uuid': '14', 'id':14, 'name':'4号服务器', 'ip':'', 'apps': ''},
                  {'uuid': '15', 'id':15, 'name':'5号服务器', 'ip':'', 'apps': ''},
                  {'uuid': '16', 'id':16, 'name':'6号服务器', 'ip':'', 'apps': ''},
                  {'uuid': '17', 'id':17, 'name':'7号服务器', 'ip':'', 'apps': ''}
                ]
              }
            },
			{
			  cabinet: 
			  {
			    'uuid': '11',
			    'id': 11, 
			    'name':'11号机柜', 
			    'size': {w: 30, h: 70, d: 30}, 
			    'position': {x: -40, y: 0, z: 50},
			    'servers': [
			      {'uuid': '11', 'id':11, 'name':'1号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '12', 'id':12, 'name':'2号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '13', 'id':13, 'name':'3号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '14', 'id':14, 'name':'4号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '15', 'id':15, 'name':'5号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '16', 'id':16, 'name':'6号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '17', 'id':17, 'name':'7号服务器', 'ip':'', 'apps': ''}
			    ]
			  }
			},
			{
			  cabinet: 
			  {
			    'uuid': '1',
			    'id': 1, 
			    'name':'1号机柜', 
			    'size': {w: 30, h: 70, d: 30}, 
			    'position': {x: 20, y: 0, z: 50},
			    'servers': [
			      {'uuid': '11', 'id':11, 'name':'1号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '12', 'id':12, 'name':'2号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '13', 'id':13, 'name':'3号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '14', 'id':14, 'name':'4号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '15', 'id':15, 'name':'5号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '16', 'id':16, 'name':'6号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '17', 'id':17, 'name':'7号服务器', 'ip':'', 'apps': ''}
			    ]
			  }
			},
			{
			  cabinet: 
			  {
			    'uuid': '1',
			    'id': 1, 
			    'name':'1号机柜', 
			    'size': {w: 30, h: 70, d: 30}, 
			    'position': {x: 50, y: 0, z: 50},
			    'servers': [
			      {'uuid': '11', 'id':11, 'name':'1号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '12', 'id':12, 'name':'2号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '13', 'id':13, 'name':'3号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '14', 'id':14, 'name':'4号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '15', 'id':15, 'name':'5号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '16', 'id':16, 'name':'6号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '17', 'id':17, 'name':'7号服务器', 'ip':'', 'apps': ''}
			    ]
			  }
			},
			{
			  cabinet: 
			  {
			    'uuid': '1',
			    'id': 1, 
			    'name':'1号机柜', 
			    'size': {w: 30, h: 70, d: 30}, 
			    'position': {x: 80, y: 0, z: 50},
			    'servers': [
			      {'uuid': '11', 'id':11, 'name':'1号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '12', 'id':12, 'name':'2号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '13', 'id':13, 'name':'3号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '14', 'id':14, 'name':'4号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '15', 'id':15, 'name':'5号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '16', 'id':16, 'name':'6号服务器', 'ip':'', 'apps': ''},
			      {'uuid': '17', 'id':17, 'name':'7号服务器', 'ip':'', 'apps': ''}
			    ]
			  }
			},
            {
              cabinet: 
              {
                'uuid': '2',
                'id': 2, 
                'name':'2号机柜', 
                'size': {w: 30, h: 70, d: 30}, 
                'position': {x:10, y: 0, z: -50}, 
                'servers': [
                  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''}
                ]
              }
            },
            {
              cabinet: 
              {
                'uuid': '3',
                'id': 3, 
                'name':'3号机柜', 
                'size': {w: 30, h: 70, d: 30}, // 尺寸
                'position': {x: -50, y: 0, z: -50}, // 位置
                'servers': [
                  {'uuid': '31', 'id':31, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''}
                ]
              }
            },
			{
			  cabinet: 
			  {
			    'uuid': '4',
			    'id': 4, 
			    'name':'4号机柜', 
			    'size': {w: 30, h: 70, d: 30}, // 尺寸
			    'position': {x: -20, y: 0, z: -50}, // 位置
			    'servers': [
			      {'uuid': '31', 'id':31, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''}
			    ]
			  }
			},
			{
			  cabinet: 
			  {
			    'uuid': '4',
			    'id': 4, 
			    'name':'4号机柜', 
			    'size': {w: 30, h: 70, d: 30}, // 尺寸
			    'position': {x: 40, y: 0, z: -50}, // 位置
			    'servers': [
			      {'uuid': '31', 'id':31, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''}
			    ]
			  }
			},
			{
			  cabinet: 
			  {
			    'uuid': '4',
			    'id': 4, 
			    'name':'4号机柜', 
			    'size': {w: 30, h: 70, d: 30}, // 尺寸
			    'position': {x: 70, y: 0, z: -50}, // 位置
			    'servers': [
			      {'uuid': '31', 'id':31, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''}
			    ]
			  }
			},
			{
			  cabinet: 
			  {
			    'uuid': '4',
			    'id': 4, 
			    'name':'4号机柜', 
			    'size': {w: 30, h: 70, d: 30}, // 尺寸
			    'position': {x: 100, y: 0, z: -50}, // 位置
			    'servers': [
			      {'uuid': '31', 'id':31, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''},
				  {'uuid': '21', 'id':21, 'name':'', 'ip':'', 'apps': ''}
			    ]
			  }
			},
			
			
          ];
          
          // 处理服务器打开、关闭时，信息的展示和隐藏
          function openServer(o) {
            loginfo('open:'+o.container.info.id+','+o.container.info.name+'--'+o.info.id+','+o.info.name);
			//renderDiv(o);
          }
          function closeServer(o) {
            loginfo('close:'+o.container.info.id+','+o.container.info.name+'--'+o.info.id+','+o.info.name);
			//renderDiv(o);
          }
          
          // 处理机柜打开、关闭时，信息的展示和隐藏
          function openCabinet(o) {
            loginfo('open:'+o.info.id+','+o.info.name);
			renderDiv(o);
          }
          function closeCabinet(o) {
            loginfo('close:'+o.info.id+','+o.info.name);
			//renderDiv(o);
          }
          
          // 处理鼠标HHover服务器时，服务器信息的内容渲染
          function hoverServer(o) {
            openHover(o.info.uuid, function() {
              loginfo('open:'+o.container.info.id+','+o.container.info.name+'--'+o.info.id+','+o.info.name);
            });
			//renderDiv(o);
          }
          
          // 处理鼠标HHover机柜时，机柜信息的内容渲染
          function hoverCabinet(o) {
            openHover(o.info.uuid, function() {
              loginfo('hover:'+o.info.id+','+o.info.name, o);
            });
			//renderDiv(o);
          }
          
          // 鼠标Hover时的通用方法
          var curHoverUUID = null;
          function openHover(hoverUUID, callback) {
            if (curHoverUUID == hoverUUID) return;
            curHoverUUID = hoverUUID;
            callback();
          }
          function closeHover() {
            curHoverUUID = null;
			document.getElementById('info').style.display = "none";
          }
          
          init();
          animate();

          //
          function init() {
            // 场景
            scene = new THREE.Scene();
            
            // 相机
            var VIEW_ANGLE = 50, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 2000;
            
            camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
            scene.add(camera);
            camera.position.set(0,200,550);
            camera.lookAt(scene.position);
				  
            // 渲染器
            if ( Detector.webgl )
              renderer = new THREE.WebGLRenderer( {
				  antialias:true,//开启锯齿
				  } );
            else
              renderer = new THREE.CanvasRenderer();

			  
			  renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
			//当界面改变时重新渲染canvas尺寸
			window.οnresize = function(){
				renderer.setPixelRatio(window.devicePixelRatio);//设备像素比，防止画布输出模糊
				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();
				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
			};
			renderer.setClearColor(0x000F1E, 1);//设置背景颜色
            container.appendChild( renderer.domElement );
          
            // 鼠标控件
            controls = new THREE.OrbitControls(camera, renderer.domElement);
            controls.addEventListener('change', render);
            
            // 性能插件
            stats = new Stats();
            stats.domElement.style.position = 'absolute';
            stats.domElement.style.top = '0px';
            stats.domElement.style.zIndex = 100;
            container.appendChild( stats.domElement );
            
            // 光源
            var light = new THREE.PointLight(0x00ff00);
            light.position.set(0,100,0);
            scene.add(light);
            
			// 初始化模型
            initModel();
            
            projector = new THREE.Projector();

            //鼠标监听事件
            document.addEventListener( 'mousedown', onDocumentMouseDown, false );
            document.addEventListener( 'mousemove', onDocumentMouseMove, false );
          }
          
          function initModel() {

            // 地板
            createFloor(600, 550);

            // 墙
            createWall(600, 80, 0, 41, -275, 0, 0, 0);//墙的背面
			createWall(450, 80, -70, 41, 272, 0, 0, 0);//墙的正面
			createWall(90, 80, 250, 41, 272, 0, 0, 0);//墙的正面
			createWall(550, 80, -296, 41, 0, 0, -Math.PI / 2, 0);//墙的左侧
			createWall(550, 80, 296, 41, 0, 0, -Math.PI / 2, 0);//墙的右侧
			
			// 玻璃墙
			createGlassWall(80, 80, 250, 41, 155, 0, 0, 0);
			createGlassWall(80, 80, -250, 41, 155, 0, 0, 0);
			createGlassWall(300, 80, 0, 41, 155, 0, 0, 0);
            
			// 灭火器
            createFireExtinguisher(8, 30, 285, 16, 140);
            createFireExtinguisher(8, 30, -285, 16, 140);
			
            // 空调
            createStandAir(30, 70, 15, 200, 36, -264);
            createStandAir(30, 70, 15, -200, 36, -264);
            
            // 门
            var door_right = createDoor( 50, 80, 180, 41, 272, 0, 0, 0);
            door_right.toggle = function(o) {
              if ( o.rotation.y == 0 ) {
                o.rotation.y = o.rotation.y + Math.PI / 2;
                o.position.x = o.position.x + 25;
                o.position.z = o.position.z + 25;
              } else {
                o.rotation.y = o.rotation.y - Math.PI / 2;
                o.position.x = o.position.x - 25;
                o.position.z = o.position.z - 25;
              }
            }
			
			// 门柱
			createColumn(10, 80, 295, 41, 155);
			createColumn(10, 80, -295, 41, 155);
			createColumn(10, 80, 210, 41, 155);
			createColumn(10, 80, -210, 41, 155);
			createColumn(10, 80, 150, 41, 155);
			createColumn(10, 80, -150, 41, 155);

			// 窗户
			// var windw = createWindow( 150, 50, 0, 41, 180, 0, 0, 0 );
			// windw.toggle = function(o) {
			//   if ( o.rotation.x == 0 ) {
			//     o.rotation.x = o.rotation.x + Math.PI / 4;
			//   } else {
			//     o.rotation.x = o.rotation.x - Math.PI / 4;
			//   }
			// }
			
            // 机柜
            for (var i=0; i<model.length; i++) {
              var c = model[i].cabinet;
              createCabinet(c.size.w, c.size.h, c.size.d, c.position.x, c.position.y, c.position.z, c);
            }
            
			// 盆栽
			// 285, 16, 140
			var position1 = {x: 280, y: 16, z: 140};
			createPlant(position1, 0.8);
			
			// 标签语
			 var markLogo = createMark(150, 20, 0, 50, -264);
          }
		  
		  // var markLogo = createMark(150, 20, 0, 50, -264);
          
		 
        // 模型函数
		
		// 给模型添加文字注释
		// var canvas = document.getElementById('canvas');
		// var ctx = canvas.getContext('2d');
		// 	canvas.width = 300;
		// 	canvas.height = 300;
		// 	// 制作矩形
		// 	ctx.fillStyle = "rgba(255, 165, 0, 0.8)";
		// 	ctx.fillRect(0, 0, 300, 300);
		// 	//设置文字
		// 	ctx.fillStyle = "#fff";
		// 	ctx.font = 'normal 18pt "楷体"'
		// 	ctx.fillText('模型介绍', 100, 20)
		// 	var textWord = '该模型由张哲瀚女朋友制作完成'
		// 	//文字换行
		// 	var len = parseInt(textWord.length / 10)
		// 	for (var i = 0; i < (len + 1); i++) {
		// 	  var space = 10
		// 	  if (i === len) {
		// 	    space = textWord.length - len * 10
		// 	  }
		// 	  console.log('len+' + len, 'space+' + space)
		// 	  var word = textWord.substr(i * 10, space)
		// 	  ctx.fillText(word, 15, 60*(i+1))
		// 	}
		
			// 创建标语
			function createMark( w, h, px, py, pz) {
				var texture = new THREE.ImageUtils.loadTexture('img/mark2.png');
				texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
				texture.repeat.set( 1, 1 );
				var markGeometry = new THREE.PlaneGeometry( w, h);
				var markMaterial = new THREE.MeshBasicMaterial( { map: texture});
				var mark = new THREE.Mesh( markGeometry, markMaterial);
				
				mark.position.x = px;
				mark.position.y = py;
				mark.position.z = pz;
				
				scene.add(mark);
				targetList.push(mark);
			}
		   
		   // 机柜
		  function createCabinet(w, h, d, px, py, pz, c) {
            var cabinet = {};
            
            // 机柜的后
            var geometry = new THREE.BoxGeometry(w, h, 2);
            var meterial = new THREE.MeshBasicMaterial( { color: 0x777777, opacity: 0.2, transparent: true } );
            
            var back = new THREE.Mesh( geometry, meterial );

            back.position.x = px;
            back.position.y = py + h / 2 + 1;
            back.position.z = pz - d / 2 + 2;
            
            back.hover = function(o) {
              hoverCabinet(o.container);
            }
            back.container = cabinet;

            targetList.push(back);
            scene.add(back);
            cabinet.back = back;
          
            // 机柜的左、右
            var geometry = new THREE.BoxGeometry(w, h, 2);
            var meterial = new THREE.MeshBasicMaterial( { color: 0x777777, opacity: 0.9, transparent: true } );
            
            var left = new THREE.Mesh( geometry, meterial );
            var right = new THREE.Mesh( geometry, meterial );
            
            left.position.x = px + w / 2 -1;
            left.position.y = py + h / 2 + 1;
            left.position.z = pz;
            left.rotation.y = Math.PI / 2;

            right.position.x = px - w / 2 +1;
            right.position.y = py + h / 2 + 1;
            right.position.z = pz;
            right.rotation.y = -Math.PI / 2;
            
            left.hover = function(o) {
              hoverCabinet(o.container);
            }
            left.container = cabinet;
            right.hover = function(o) {
              hoverCabinet(o.container);
            }
            right.container = cabinet;

            targetList.push(left);
            targetList.push(right);
            scene.add(left);
            scene.add(right);
            
            cabinet.left = left;
            cabinet.right = right;
            
            // 机柜的底部、顶部
            var geometry = new THREE.BoxGeometry(w, 2, d);
            var meterial = new THREE.MeshBasicMaterial( { color: 0x222222, transparent: true } );
            
            var top = new THREE.Mesh( geometry, meterial );
            var bottom = new THREE.Mesh( geometry, meterial );
            
            top.position.x = px;
            top.position.y = py + h + 2;
            top.position.z = pz;
            
            bottom.position.x = px;
            bottom.position.y = py + 2;
            bottom.position.z = pz;
            
            top.hover = function(o) {
              hoverCabinet(o.container);
            }
            top.container = cabinet;
            bottom.hover = function(o) {
              hoverCabinet(o.container);
            }
            bottom.container = cabinet;
            
            targetList.push(top);
            targetList.push(bottom);
            scene.add(top);
            scene.add(bottom);
            
            cabinet.top = top;
            cabinet.bottom = bottom;
            
            // 机柜门
            var geometry = new THREE.BoxGeometry(w, h, 2);
            var meterial = new THREE.MeshBasicMaterial( { color: 0x003333, opacity: 0.5, transparent: true } );
            
            var front = new THREE.Mesh( geometry, meterial );
            
            front.position.x = px;
            front.position.y = py + h / 2 + 1;
            front.position.z = pz + d / 2;
            front.toggle = function(o) {
              if ( o.rotation.y == 0 ) {
                o.rotation.y = o.rotation.y + Math.PI * 3 / 5;
                o.position.x = o.position.x + w / 2 + 3;
                o.position.z = o.position.z + d / 2;
                
                openCabinet(o.container);
              } else {
                o.rotation.y = o.rotation.y - Math.PI * 3 / 5;
                o.position.x = o.position.x - w / 2 - 3;
                o.position.z = o.position.z - d / 2;
                
                // 关闭机柜门时，将机柜中的服务器收起
                for (var i=0; i<o.container.servers.length; i++) {
                  o.container.servers[i].toggle(o.container.servers[i], false);
                }
                
                closeCabinet(o.container);
              }
            }
            front.hover = function(o) {
              hoverCabinet(o.container);
            }
            front.container = cabinet;
            
            scene.add(front);
            targetList.push(front);
            
            cabinet.front = front;
            
			// 机柜中的服务器
            cabinet.servers = [];

            if (c && c.servers) {
              cabinet.info = c;
              for (var i=0; i<c.servers.length; i++) {
                var server = createServer(w-4, 4, d-4, px, py + (9*(i+1)), pz+2);   // 服务器的厚度默认为 4， 服务器之间的间隔为 5
                server.container = cabinet;
                server.info = c.servers[i];
                cabinet.servers.push(server);
              }
            }
            
            return cabinet;
          }
          
		  // 服务器
          function createServer(w, h, d, px, py, pz) {
			// 服务器前面添加贴图
			var texture = new THREE.ImageUtils.loadTexture( 'img/server.png' );
            texture.wrapS = texture.wrapT = THREE.RepeatWrapping; 
            texture.repeat.set( 1, 1 );
			// 添加服务器后面贴图
            var texture_back = new THREE.ImageUtils.loadTexture( 'img/server-back.png' );
            texture_back.wrapS = texture_back.wrapT = THREE.RepeatWrapping; 
            texture_back.repeat.set( 1, 1 );

            var geometry = new THREE.BoxGeometry(w, h, d);
            var materialArray = [];
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { map: texture } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { map: texture_back } ) );
            var material = new THREE.MeshFaceMaterial( materialArray );

            var server = new THREE.Mesh( geometry, material );
            
            server.position.x = px;
            server.position.y = py;
            server.position.z = pz;
            
            server.toggle = function(o, openOrClose) {
              // 关闭同一机柜中的其他服务器
              for (var i=0; i<o.container.servers.length; i++) {
                if ( o === o.container.servers[i] ) continue;
                if ( o.container.servers[i].position.z == pz ) {
                } else {
                  o.container.servers[i].position.z = o.container.servers[i].position.z - d / 2; 
                  closeServer(o.container.servers[i]);
                }
              }
              
              if ( o.position.z == pz ) {
                if ( openOrClose == null || openOrClose ) {
                  o.position.z = o.position.z + d / 2;
                  // 打开服务器时，处理其他逻辑
                  openServer(o);
                }
              } else {
                if ( openOrClose == null || !openOrClose ) {
                  o.position.z = o.position.z - d / 2;
                  // 关上服务器时，处理其他逻辑
                  closeServer(o);
                }
              }
            }
            server.hover = function(o) {
              hoverServer(o);
            }
            
            scene.add(server);
            targetList.push(server);
            
            return server;
          }
          
		  // 创建空调
          function createStandAir(w, h, d, px, py, pz) {
            // var texture = new THREE.ImageUtils.loadTexture( '' );
            var texture = new THREE.ImageUtils.loadTexture('img/airCondition.png');
			texture.wrapS = texture.wrapT = THREE.RepeatWrapping; 
            texture.repeat.set( 1, 1 );
            
            var geometry = new THREE.BoxGeometry(w, h, d);
          
            var materialArray = [];
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { map: texture } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            var material = new THREE.MeshFaceMaterial( materialArray );

            var air = new THREE.Mesh( geometry, material );
            
            air.position.x = px;
            air.position.y = py;
            air.position.z = pz;
            
            scene.add(air);
            targetList.push(air);
            
            return air;
          }
          
		  // 创建地板
          function createFloor(width, height) {
			  //var texture = new THREE.ImageUtils.loadTexture( '' );
			//var texture = new THREE.ImageUtils.loadTexture('img/floor1.jpg');
			// texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
			// texture.repeat.set( 1, 1 );
            var floorGeometry = new THREE.PlaneGeometry(width, height);
            var floorMaterial = new THREE.MeshBasicMaterial( { color: 0x488CAC, transparent: true, opacity: 0.4, side: THREE.DoubleSide} );
            var floor = new THREE.Mesh(floorGeometry, floorMaterial);
            
            floor.rotation.x = Math.PI / 2;

            scene.add(floor);
            targetList.push(floor);
            
            return floor;
          }
		  
			// 创建墙面
          function createWall(w, h, px, py, pz, rx, ry, rz) {
            var wallTexture = new THREE.ImageUtils.loadTexture( '' );
			//var wallTexture = new THREE.ImageUtils.loadTexture('img/floor2.JPG');
			// wallTexture.wrapS = wallTexture.wrapT = THREE.RepeatWrapping; 
   //          wallTexture.repeat.set(w / 40, h / 40);

            var wallGeometry = new THREE.BoxGeometry(w, h, 5);
            var wallMaterial = new THREE.MeshBasicMaterial( { color: 0x488CAC, transparent: true, opacity: 0.4, side: THREE.DoubleSide} );
            var wall = new THREE.Mesh( wallGeometry, wallMaterial );
            wall.position.x = px;
            wall.position.y = py;
            wall.position.z = pz;
            
            wall.rotation.y = ry;
            
            scene.add(wall);
            targetList.push(wall);
            
            return wall;
          }
          
		  // 创建玻璃墙
		  function createGlassWall(w, h, px, py, pz, rx, ry, rz) {
		    var geometry = new THREE.BoxGeometry(w, h, 5);
		    var meterial = new THREE.MeshBasicMaterial( { color: 0x488CAC, opacity: 0.4, transparent: true, side: THREE.DoubleSide } );
		    var glassW = new THREE.Mesh( geometry, meterial );
		    
		    glassW.position.x = px;
		    glassW.position.y = py;
		    glassW.position.z = pz;
		    
		    glassW.rotation.y = ry;
		    
		    scene.add(glassW);
		    targetList.push(glassW);
		    
		    return glassW;
		  }
		  
		  // 创建门柱
		  function createColumn(w, h, px, py, pz) {
			// var texture = new THREE.ImageUtils.loadTexture('img/01.jpg');
			// texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
			// texture.repeat.set(1,1);
		    var geometry = new THREE.BoxGeometry(w, h, w);
		    var meterial = new THREE.MeshBasicMaterial( { color: 0xffffff, side: THREE.DoubleSide } );
		    var column = new THREE.Mesh( geometry, meterial );
		    
		    column.position.x = px;
		    column.position.y = py;
		    column.position.z = pz;
		    
		    scene.add(column);
		    targetList.push(column);
		    
		    return column;
		  }
		  
		  // 创建门
		  function createDoor(w, h, px, py, pz, rx, ry, rz) {
            // var texture = new THREE.ImageUtils.loadTexture( '' );
            var texture = new THREE.ImageUtils.loadTexture('img/door.png');
			texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
            texture.repeat.set( w / 50, w / 50 );
            
            var geometry = new THREE.BoxGeometry(w, h, 3);
            var material = new THREE.MeshBasicMaterial( { map: texture, side: THREE.DoubleSide } );
            var door = new THREE.Mesh( geometry, material );
            door.position.x = px;
            door.position.y = py;
            door.position.z = pz;
            
            scene.add(door);
            targetList.push(door);
            
            return door;
          }
          
		  // 创建窗户
		  function createWindow(w, h, px, py, pz, rx, ry, rz) {
            var geometry = new THREE.PlaneGeometry(w, h);
            var meterial = new THREE.MeshBasicMaterial( { color: 0x00fff0, opacity: 0.5, transparent: true, side: THREE.DoubleSide } );
            var windw = new THREE.Mesh( geometry, meterial );
            
            windw.position.x = px;
            windw.position.y = py;
            windw.position.z = pz;
            
            scene.add(windw);
            targetList.push(windw);
            
            return windw;
          }
          
		  // 创建灭火器
          function createFireExtinguisher(w, h, px, py, pz) {
            var texture = new THREE.ImageUtils.loadTexture( '' );
            texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
            texture.repeat.set( 1, 1 );
            
            var geometry = new THREE.CylinderGeometry( w, w, h, 20, 4 );

            var materialArray = [];
            materialArray.push( new THREE.MeshBasicMaterial( { map: texture } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            materialArray.push( new THREE.MeshBasicMaterial( { color: 0xbbbbbb } ) );
            var material = new THREE.MeshFaceMaterial( materialArray );
            
            var fe = new THREE.Mesh( geometry, material );
            fe.position.x = px;
            fe.position.y = py;
            fe.position.z = pz;
            
            scene.add(fe);
            targetList.push(fe);
            

            var geometry = new THREE.SphereGeometry( w, 32, 16, 0, 2 * Math.PI, 0, Math.PI / 2 );
            var material = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
            var fe = new THREE.Mesh( geometry, material );
            fe.position.x = px;
            fe.position.y = py + h / 2;
            fe.position.z = pz;
            
            scene.add(fe);
            targetList.push(fe);

            var geometry = new THREE.CylinderGeometry( 3, 3, 5, 20, 4 )
            var material = new THREE.MeshBasicMaterial( { color: 0x000000 } );
            var fe = new THREE.Mesh( geometry, material );
            fe.position.x = px;
            fe.position.y = py + h / 2 + w;
            fe.position.z = pz;
            
            scene.add(fe);
            targetList.push(fe);
            
          }
          
		  // 创建盆栽
		  function createPlant(position, scale) {
			  console.log(position);
			  var plant = new THREE.Object3D();
			  // 花盆底座
			  var geometry = new THREE.CylinderGeometry( 0.15, 0.1, 0.4, 22);
			  var material = new THREE.MeshLambertMaterial( {color: 0xffffff});
			  var cylinder = new THREE.Mesh( geometry, material);
			  cylinder.position.x = 0;
			  cylinder.position.y = 0.2;
			  cylinder.position.z = 0;
			  plant.add(cylinder);
			  // 绿叶
			  var leafTexture = new THREE.ImageUtils.loadTexture('img/leaf.png');
			  leafTexture.wrapS = leafTexture.wrapT = THREE.RepeatWrapping;
			  leafTexture.repeat.set(1,1);
			  var leafMaterial = new THREE.MeshLambertMaterial( {map: leafTexture, side: THREE.DoubleSide});
			  var gemo = new THREE.PlaneGeometry(0.4, 0.8);
			  for(var i=0; i < 4; i++){
				  var leaf = new THREE.Mesh( gemo, leafMaterial);
				  leaf.position.y = 0.8;
				  leaf.rotation.y = -Math.PI/(i+1);
				  plant.add(leaf);
			  }
			  plant.position.x = position.x;
			  plant.position.y = position.y;
			  plant.position.z = position.z;
			  scene.add(plant);
			  targetList.push(plant);
		  }
          
		  function onDocumentMouseMove( event ) {
			  
            mouse.x = ( event.clientX / SCREEN_WIDTH ) * 2 - 1;
            mouse.y = - ( event.clientY / SCREEN_HEIGHT ) * 2 + 1;
          
            var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
            projector.unprojectVector( vector, camera );
            var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );

            var intersects = ray.intersectObjects( targetList );

            if ( intersects.length > 0 ){
              var o = intersects[ 0 ].object;
              if (typeof o.hover == 'function') {
                o.hover(o);
              } else {
                closeHover();
              }
            }
          }
          
          function onDocumentMouseDown( event ) {
			  //通过鼠标点击位置，计算出raycaster所需点的位置，以屏幕为中心点，范围-1到1
            mouse.x = ( event.clientX / SCREEN_WIDTH ) * 2 - 1;
            mouse.y = - ( event.clientY / SCREEN_HEIGHT ) * 2 + 1;
            var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
            projector.unprojectVector( vector, camera );
            var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
			// 获取与射线相交的对象数组，其中的元素按照距离排序
            var intersects = ray.intersectObjects( targetList );

            if ( intersects.length > 0 ){
                var o = intersects[ 0 ].object;
                if (typeof o.toggle == 'function') {
                  o.toggle(o);
                }
            }
          }
		  
		  // 更新div的位置
		  function renderDiv(object){
			  x = object.info.position.x;
			  y = object.info.position.y;
			  z = object.info.position.z;
			  var vec3 = new THREE.Vector3( x, y, z);
			  // 获取窗口的一半高度和宽度
			  var halfWidth = window.innerWidth / 2;
			  var halfHeight = window.innerHeight / 2;			 
			  
			  // 逆转相机求出二维坐标
			  var posi = vec3.project(camera);
			  // 修改div位置
			  document.getElementById('info').style.display = "block";
			  document.getElementById('info').style.left = (posi.x * halfWidth + halfWidth) + "px";
			  document.getElementById('info').style.top = (-posi.y * halfHeight + halfHeight) + "px";
		  }
          

          function animate() {
              requestAnimationFrame( animate );
              render();		
              update();
          }
		  
		  // 更新插件
		  function update(){    
		    controls.update();
		    stats.update();
			//markLogo.offset.x += 0.001;
		  }
          

          function render() {
              renderer.render( scene, camera );
          }
		  
		  
		</script>
	</body>
</html>
